package com.zhongke.common.base.activity;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProviders;

import com.alibaba.android.arouter.launcher.ARouter;
import com.billy.android.swipe.SmartSwipe;
import com.billy.android.swipe.SmartSwipeWrapper;
import com.billy.android.swipe.SwipeConsumer;
import com.billy.android.swipe.consumer.ActivitySlidingBackConsumer;
import com.billy.android.swipe.listener.SimpleSwipeListener;
import com.zhongke.common.R;
import com.zhongke.common.base.viewmodel.ZKBaseViewModel;
import com.zhongke.common.base.viewmodel.ZKIBaseView;
import com.zhongke.common.utils.ZKStatusBarUtil;
import com.zhongke.common.widget.TitleView;
import com.zhongke.common.widget.ZKLoadingView;
import com.zhongke.common.widget.statusview.ZKLoadViewHelper;
import com.zhongke.common.widget.statusview.ZKStatusViewHelper;

import org.jetbrains.annotations.NotNull;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;


/**
 * 一个拥有DataBinding框架的基Activity
 */
public abstract class ZKBaseActivity<V extends ViewDataBinding, VM extends ZKBaseViewModel> extends AppCompatActivity
        implements ZKIBaseView, EasyPermissions.PermissionCallbacks {
    protected V binding;
    protected VM viewModel;
    protected int viewModelId;
    protected Context mContext;
    protected Activity mActivity;
    protected Bundle savedInstanceState;
    protected SwipeConsumer swipeConsumer;
    private ZKLoadingView mLoading;
    private ViewGroup mRootView;
    protected TitleView mTitleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getApplicationContext();
        mActivity = this;
        //页面接受的参数方法
        initParam();
        setOrientation();
        //私有的初始化Databinding和ViewModel方法
        initViewDataBinding(savedInstanceState);
        //侧滑返回界面
        initSmartSwipe();
        //网络请求观察者
        onCreateObserver();
        //先调用这个方法再调用下面的initData()
        initLoadingHelper();
        //页面数据初始化方法
        initData();
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initViewObservable();
        //地图需要
        initDataMap(savedInstanceState);
        //TODO 需要刪掉下面这行初始化代码
        ARouter.init(getApplication());
        ARouter.getInstance().inject(this);
    }

    protected void setOrientation() { //固定竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    protected boolean isIncludeTitleView() {
        return false;
    }

    /**
     * 注入绑定
     */
    private void initViewDataBinding(Bundle savedInstanceState) {
        this.savedInstanceState = savedInstanceState;
        //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包

        if (isIncludeTitleView()) {
            LinearLayoutCompat root = new LinearLayoutCompat(this);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams
                    (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            root.setLayoutParams(lp);
            root.setOrientation(LinearLayoutCompat.VERTICAL);

            mTitleView = new TitleView(this, null);
            lp = new LinearLayoutCompat.LayoutParams
                    (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            root.addView(mTitleView, lp);

            FrameLayout container = new FrameLayout(this);
            container.setId(R.id.view_content);
            lp = new LinearLayoutCompat.LayoutParams
                    (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            root.addView(container, lp);

            binding = DataBindingUtil.inflate(getLayoutInflater(), initContentView(savedInstanceState), container, true);
            setContentView(root);
        } else {
            binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));
        }

        viewModelId = initVariableId();
        viewModel = initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = ZKBaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        //关联ViewModel
        binding.setVariable(viewModelId, viewModel);
        //支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
    }


    public void showDialog(String title) {
//        if (dialog == null) {
//            dialog = ZKDialogUtils.loadingDialogs(this,title);
//        }
//        dialog.show();
        if (mRootView == null) {
            mRootView = findViewById(android.R.id.content);
        }
        if (mLoading == null) {
            mLoading = new ZKLoadingView(mContext);
            if (mRootView != null) {
                mRootView.addView(mLoading, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                mLoading.setOnClickListener(v -> { });
            }
        }
        mLoading.show(title);
    }

    public void dismissDialog() {
        /*if (this.isFinishing() || this.isDestroyed()){
            return;
        }
        if (dialog == null || !dialog.isShowing()) {
            return;
        }
        dialog.dismiss();*/
        if (mLoading != null) {
            mLoading.dismiss();
        }

    }

    @Override
    public void initParam() {

    }

    /**
     * 初始化根布局
     *
     * @return 布局layout的id
     */
    public abstract int initContentView(Bundle savedInstanceState);

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    public abstract int initVariableId();

    /**
     * 地图需要
     */

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    public VM initViewModel() {
        return null;
    }

    @Override
    public void initData() {
    }

    public void initDataMap(Bundle savedInstanceState) {
    }

    @Override
    public void initViewObservable() {
    }

    /**
     * 创建ViewModel
     *
     * @param cls
     * @param <T>
     * @return
     */
    public <T extends ViewModel> T createViewModel(FragmentActivity activity, Class<T> cls) {
        return ViewModelProviders.of(activity).get(cls);
    }

    //1.权限请求需要先重写onRequestPermissionsResult()方法，把结果转发给EasyPermissions框架
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // 将结果转发到 EasyPermissions框架，固定写法。
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    //2.发起权限请求，在此之前先判断是否已经请求过了
    protected void requestPermission(List<String> list) {
        requestPermission(list, 0);

    }

    //2.发起权限请求，在此之前先判断是否已经请求过了
    protected void requestPermission(List<String> list, int requestCode) {
        if (EasyPermissions.hasPermissions(this, list.toArray(new String[list.size()]))) {
            //具备权限 直接进行操作
            onPermissionSuccess(requestCode);
        } else {
            //权限拒绝 申请权限
            EasyPermissions.requestPermissions(this, "为了正常使用，需要获取以下权限", requestCode, list.toArray(new String[list.size()]));
        }

    }

    //3.请求成功的权限
    @Override
    public void onPermissionsGranted(int requestCode, @NonNull @NotNull List<String> perms) {
        onPermissionSuccess(requestCode);
    }

    //4.被拒绝的权限
    @Override
    public void onPermissionsDenied(int requestCode, @NonNull @NotNull List<String> perms) {
        /**
         * 若是在权限弹窗中，用户勾选了 '不再提示'，且拒绝权限。
         * 这时候，需要跳转到设置界面去，让用户手动开启。
         */
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            //拒绝了权限，而且选择了不再提醒，需要去手动设置
            new AppSettingsDialog.Builder(this)
                    .setTitle("权限请求")
                    .setRationale("需要在设置中开启权限")
                    .build()
                    .show();
        } else {
            //拒绝了权限，重新申请
            onPermissionFail(requestCode);
        }
    }

    /**
     * 权限申请成功执行方法
     */
    protected void onPermissionSuccess(int requestCode) {

    }

    /**
     * 权限申请失败
     */
    protected void onPermissionFail(int requestCode) {

    }

    protected void onCreateObserver() {

    }

    /**
     * 初始化滑动返回
     */
    private void initSmartSwipe() {
        if (isSupportSwipeBack()) {
            swipeConsumer = SmartSwipe.wrap(this)//view
                    .addConsumer(new ActivitySlidingBackConsumer(this))//关闭界面的样式
                    .setRelativeMoveFactor(0.5f)//设置抽屉视图相对于内容视图的移动因子
                    .setScrimColor(Color.TRANSPARENT)//松开的界面颜色
                    .setShadowColor(0x80000000)//内容视图边缘阴影的颜色
                    .setShadowSize(SmartSwipe.dp2px(10, this))//内容视图边缘阴影的大小
                    .setEdgeSize(SmartSwipe.dp2px(100, this))// //边缘触发区域尺寸像素值（dp需转换为px），若设置为0，则表示整个activity区域都可触发
                    .enableDirection(SwipeConsumer.DIRECTION_LEFT)//方向
                    .addListener(new SimpleSwipeListener() {
                        @Override
                        public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                            finish();
                            overridePendingTransition(R.anim.anim_none, R.anim.anim_none);
                        }
                    });
        }
    }

    /**
     * 是否支持滑动返回。
     * true 支持滑动返回，
     * false 不支持滑动返回，则重写该方法
     */
    public boolean isSupportSwipeBack() {
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        //当页面暂停时，统一关闭软键盘
        if (getCurrentFocus() != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
//        initTitleNameList();
/*        // 判断系统开启了深色夜间模式，按位与运算
        int isNight = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
        if (isNight == Configuration.UI_MODE_NIGHT_YES) {
            //是夜间模式
            Log.e("TAG", "是夜间模式: ");
        } else {
            //不是夜间模式
            Log.e("TAG", "不是夜间模式: ");
        }*/

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (binding != null) {
            binding.unbind();
        }
    }



    //-----------------------------以下加载布局StatusView相关----------------------------------

    /**
     * 界面加载助手
     */
    private ZKLoadViewHelper loadViewHelper;


    /**
     * 初始化界面加载助手
     */
    public void initLoadingHelper() {
        View content = findViewById(R.id.view_content);
        if (loadViewHelper == null && content != null) {
            loadViewHelper = new ZKLoadViewHelper(new ZKStatusViewHelper(content));
        }
    }

    /**
     * 显示请求数据为空的界面
     */
    public void showEmptyView() {
        showEmptyView("暂无数据");
    }


    /**
     * 显示请求数据为空的界面
     * @param message:提示的文本内容
     */
    public void showEmptyView(String message) {
        loadViewHelper.showEmpty(message, R.drawable.icon_list_no_data);
    }

    /**
     * 显示出错的界面
     * @param listener:刷新按钮点击事件
     */
    public void showErrorView(View.OnClickListener listener) {
        loadViewHelper.showError(listener, "", "刷新", R.drawable.bg_load_failure3);
    }

    /**
     * 显示出错的界面
     * @param listener:刷新按钮点击事件
     * @param message：提示的文本内容
     */
    public void showErrorView(String message, View.OnClickListener listener) {
        loadViewHelper.showError(listener, message, "刷新", R.drawable.bg_load_failure3);
    }

    /**
     * 显示加载中视图
     */
    public void showLoadingView() {
        loadViewHelper.showLoading();
    }
    /**
     * 显示加载中视图
     */
    public void showLoadingTransparent() {
        loadViewHelper.showLoadingTransparent();
    }

    /**
     * 显示加载成功的界面(即展示数据的界面)
     */
    public void showContentView() {
        loadViewHelper.restore();
    }

//-----------------------------以上加载布局StatusView相关----------------------------------

    //----------------------以下设置触摸EditText外的区域隐藏软键盘-----------------------
    //是否EditText被touch
    private boolean isEditTextTouch = false;
    //是否需要统一处理软键盘，默认都会点击EditText外区域隐藏软键盘(如有需要可在事件分发里设置为false)
    private boolean isNeedManageSoftInput = true;

    public boolean isNeedManageSoftInput() {
        return isNeedManageSoftInput;
    }

    public void setNeedManageSoftInput(boolean needManageSoftInput) {
        isNeedManageSoftInput = needManageSoftInput;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN && isNeedManageSoftInput) {
            View v = getCurrentFocus();
            ViewGroup vGroup = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
            ViewGroup rootView = (ViewGroup) vGroup.getChildAt(0);
            isEditTextTouch = false;//事件触发时总是认为EditText没有被touch，因为可能上一次被touch
            isEditTextTouch(rootView, ev);
            if (!isEditTextTouch) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null && v != null)
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 遍历当前activity的子view，判断被Touch的是不是EditText
     *
     * @param rootView
     * @param event
     */
    private void isEditTextTouch(ViewGroup rootView, MotionEvent event) {
        for (int i = 0; i < rootView.getChildCount(); i++) {
            View childVg = rootView.getChildAt(i);
            if (childVg instanceof ViewGroup) {
                isEditTextTouch((ViewGroup) childVg, event);
            } else if (childVg instanceof EditText) {
                int[] leftTop = new int[2];
                //获取当前输入框相对于屏幕的位置
                childVg.getLocationOnScreen(leftTop);
                int left = leftTop[0];
                int top = leftTop[1];
                int bottom = top + childVg.getHeight();
                int right = left + childVg.getWidth();
                if (event.getRawX() > left && event.getX() < right && event.getY() > top && event.getY() < bottom) {
                    if (childVg.isEnabled()) {//touch的是一个可用的EditText
                        isEditTextTouch = true;
                        break;
                    }
                }
            }
        }
    }

}
